package com.jobsika.client;

import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.jobsika.client.footer.Footer;
import com.jobsika.client.header.Header;
import com.jobsika.client.post.PostPanel;
import com.jobsika.client.profile.Profile;
import com.jobsika.client.register.Register;
import com.jobsika.client.rpc.UserService;
import com.jobsika.client.rpc.UserServiceAsync;
import com.jobsika.client.search.SearchResultPanel;
import com.jobsika.domain.RPCPost;
import com.jobsika.domain.RPCUser;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Jobsika implements EntryPoint, ValueChangeHandler<String> {
	// Variables
	private UserServiceAsync userService = null;
	public static RPCUser user = null;
	private String query = "";
	private int page = 0;
	private int limit = 10;
	private int add = 0;
	
	// UI
	private VerticalPanel skeleton;
	private SearchResultPanel i;
	private PostPanel p;
	private Profile profile;
	private Header h;
	private Footer f;
	
	
	public void onModuleLoad() {
		if (userService == null) {
			userService = GWT.create(UserService.class);
		}
		History.addValueChangeHandler(this);
		skeleton = new VerticalPanel();
		i = new SearchResultPanel(limit);
		h = new Header();
		f = new Footer();
		
		h.login.setVisible(false);
		RootPanel.get().setStyleName("outterWrap");
		skeleton.setStyleName("basicPanel");
	    RootPanel.get("header").add(h);
		RootPanel.get("content").add(skeleton);
	    RootPanel.get("footer").add(f);
//	    History.fireCurrentHistoryState();
	    
	    h.setLoggedIn(true);
//		h.setLogoutURL(user.getLogoutUrl());
		profile = new Profile(new RPCUser("bernardw@gmail.com", "Bernard", "Wong", "Mills", "Bob"));
		History.newItem(Util.HOME);
		History.fireCurrentHistoryState();
	}

	private void registered(RPCUser result) {
		h.setLoggedIn(true);
		h.setLogoutURL(user.getLogoutUrl());
		profile = new Profile(result);
		setWidget(profile);
	}
	
	private void initialize() {
		userService.initialize(new AsyncCallback<Integer>() {

			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Integer result) {
				Window.alert("Parse Success: "+result);
			}
		});
	}

	private void getPost(String key) {

		userService.getPost(key, new AsyncCallback<RPCPost>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(RPCPost result) {
				p = new PostPanel(result);
				setWidget(p);
				Window.scrollTo(0, 0);
			}
		});
	}
	
	private void getUser(String email) {
		
		userService.getUser(email, new AsyncCallback<RPCUser>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(RPCUser result) {
				Profile tmp = new Profile(result);
				setWidget(tmp);
				Window.scrollTo(0, 0);
			}
		});
	}
	
	private void getPosts() {
		
		userService.getPosts(page, limit, new AsyncCallback<RPCPost[]>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(RPCPost[] result) {
				i.setPosts(query, page, add, result);
				setWidget(i);
			}
		});
	}
	
	private void getUsers() {
		
		userService.getUsers(page, limit, new AsyncCallback<RPCUser[]>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(RPCUser[] result) {
				i.setUsers(query, page, add, result);
				setWidget(i);
			}
		});
	}
	
	private void setWidget(Widget w) {
		skeleton.clear();
		skeleton.insert(w, 0);
	}
	
	private void getLogin() {
		userService.login(GWT.getHostPageBaseURL(), new AsyncCallback<RPCUser>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Get login Url failure!");
			}

			public void onSuccess(RPCUser result) {
				user = result;
				if (user.isLoggedIn()) {
					h.setLoggedIn(true);
					h.setLogoutURL(user.getLogoutUrl());
					profile = new Profile(result);
					History.newItem(Util.HOME);
					History.fireCurrentHistoryState();
				} else {
					h.setLoginURL(user.getLoginUrl());
					h.login.setVisible(true);
				}
			}
	    });
	}
	
	private void getRegister() {
		final Register reg = new Register();
		reg.submit.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				RPCUser user = reg.getUser();
				userService.register(user, new AsyncCallback<RPCUser>() {
					@Override
					public void onFailure(Throwable caught) {
					}

					@Override
					public void onSuccess(RPCUser result) {
						registered(result);
					}
				});
			}
		});
		setWidget(reg);
	}
	@Override
	public void onValueChange(ValueChangeEvent<String> event) {
		String queryString = event.getValue();
		Map<String, List<String>> params = Util.buildListParamMap(queryString);
		page = 0;
		add = 0;
		if (params.containsKey(Util.ADD)) {
			add = new Integer(params.get(Util.ADD).get(0));
		}
		if (params.containsKey(Util.PAGE)) {
			page = new Integer(params.get(Util.PAGE).get(0));
		}
		if (params.containsKey(Util.ACTION)) {
			String action = params.get(Util.ACTION).get(0);
			if (action.equals(Util.LOGIN)) {
//						greet();
			}
		} else if (params.containsKey(Util.HOME)) {
			setWidget(profile);
		} else if (params.containsKey(Util.USER)) {
			String u = params.get(Util.USER).toString();
			if (u.length() >= 0)
				u = u.substring(1, u.length() - 1);
			if (u.length() > 0)
				getUser(u);
		} else if (params.containsKey("init")) {
			initialize();
		} else if (params.containsKey(Util.BROWSE)) {
			query = params.get(Util.QUERY).get(0);
			if (query.equals(Util.POST)) {
				getPosts();
			} else if (query.equals(Util.USER)) {
				getUsers();
			}
		} else if (params.containsKey(Util.QUERY)) {
			query = params.get(Util.QUERY).get(0);
			search(query);
		} else if (params.containsKey(Util.POST)) {
			String p = params.get(Util.POST).toString();
			if (p.length() >= 0)
				p = p.substring(1, p.length() - 1);
			if (p.length() > 0)
				getPost(p);
		} else {
			Window.alert("Action not covered!\n"+queryString);
		}
	}
	
	private void search(String query) {
		
		userService.search(0, 10, query, new AsyncCallback<RPCPost[]>() {
			
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(RPCPost[] result) {
				i.setPosts("", page, add, result);
				setWidget(i);
			}
		});
	}
}
